package cz.muni.fi.pa165.travelagency.services;

import cz.muni.fi.pa165.travelagency.api.entities.IOrder;
import cz.muni.fi.pa165.travelagency.api.services.IOrderService;
import cz.muni.fi.pa165.travelagency.dto.OrderDTO;
import cz.muni.fi.pa165.travelagency.entities.Order;
import cz.muni.fi.pa165.travelagency.interceptors.ShiroSecured;
import cz.muni.fi.pa165.travelagency.persistence.IOrderDAO;
import java.util.ArrayList;
import java.util.List;
import javax.ejb.EJB;
import javax.ejb.Local;
import javax.ejb.Stateless;
import javax.ejb.TransactionAttribute;
import javax.ejb.TransactionAttributeType;
import javax.ejb.TransactionManagement;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.dozer.DozerBeanMapperSingletonWrapper;
import org.dozer.Mapper;

/**
 * Implementation of Order service
 *
 * @author Marián Mozola
 */
@Stateless(name = "orderService", mappedName = "orderService")
@Local(IOrderService.class)
@TransactionManagement
@ShiroSecured
public class OrderService implements IOrderService {

    private Mapper mapper = DozerBeanMapperSingletonWrapper.getInstance();
    @EJB
    private IOrderDAO orderDAO;

    public void setMapper(Mapper mapper) {
        this.mapper = mapper;
    }

    public void setOrderDAO(IOrderDAO orderDAO) {
        this.orderDAO = orderDAO;
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    @RequiresPermissions("order:create")
    public void createOrder(IOrder order) {
        Order o = mapper.map(order, Order.class);
        orderDAO.createOrder(o);
        order.setId(o.getId());
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    @RequiresPermissions("order:delete")
    public void deleteOrder(IOrder order) {
        orderDAO.deleteOrder(mapper.map(order, Order.class));
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @RequiresPermissions("order:find")
    public List<IOrder> findAll() {
        List<Order> orders = orderDAO.findAll();
        List<IOrder> result = new ArrayList<>();
        for (Order order : orders) {
            result.add(mapper.map(order, OrderDTO.class));
        }
        return result;
    }
    
    @Override		
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @RequiresPermissions("order:find")
    public List<IOrder> findUnpaid() {		
        List<Order> orders = orderDAO.findUnpaid();		
        List<IOrder> result = new ArrayList<>();		
        for (Order order : orders) {		
            result.add(mapper.map(order, OrderDTO.class));		
        }		
        return result;		
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    @RequiresPermissions("order:find")
    public IOrder getOrder(Long id) {
        Order order = orderDAO.getOrder(id);
        return order == null ? null : mapper.map(order, OrderDTO.class);
    }

    @Override
    @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
    @RequiresPermissions("order:update")
    public void updateOrder(IOrder order) {
        orderDAO.updateOrder(mapper.map(order, Order.class));
    }
}
